package com.syde322;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.syde322.LocationApp.R;
import com.syde322.FactSearch;
import com.syde322.WikiFactSearch;
import com.syde322.WikiFacts;
import com.syde322.myItemizedOverlay;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class LocationAppActivity extends MapActivity {
	
	// Members
	private static LocationProcessor loc_proc;
	private FactSearch<WikiFacts> wikiFactSearch = new WikiFactSearch();
	private ProgressDialog progressDialog;
	private static MapView mapView;
	private static int latE = 0;
	private static int lngE = 0;
	private static String locationStr = "";
	
	// Start the underlying location service
	public void init() {
		loc_proc = new LocationProcessor(this);
		loc_proc.init();
	}
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        this.init();
        LocationAppActivity.loc_proc.getLocationForProcessing();
        
        // Main button Callback
        Button fact_button = (Button)findViewById(R.id.button1);
        fact_button.setOnClickListener(new OnClickListener() {
        	public void onClick(View v){
        		
        		Geocoder myLocation = new Geocoder(getApplicationContext(), Locale.getDefault());
                List<Address> myList = null; 

                try {
                	//Reverse Geocode - get Location from Coordinates 
                	myList = myLocation.getFromLocation(latE/1000000, lngE/1000000, 1);
                	
        		} catch (IOException e) {
        			e.printStackTrace();
        		}
                
                //if Geocoder does not return results  
                if (myList == null) {
                	LayoutInflater factory = LayoutInflater.from(getApplicationContext());      
        	        final View errView = factory.inflate(R.layout.errlayout, null);
        			
        			AlertDialog.Builder errAlert = new AlertDialog.Builder(getApplicationContext());
        			errAlert.setTitle("Error.");
        			errAlert.setMessage("Reverse Geocoder: No response from Google server. Please try again later.");
        			errAlert.setView(errView);
        			AlertDialog prompt = errAlert.create();
        						
        			errAlert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        				public void onClick(DialogInterface dialog, int whichButton) {
        					dialog.cancel();
        				}
        			});
        			
        			errAlert.show();
                	Log.d("LocationProcessor", "Nothing returned from reverse geocoder."); 
                	
                } else {
                	
                	if(myList.get(0).getLocality() != null) 
                		locationStr += myList.get(0).getLocality()+", ";
                	
                	if(myList.get(0).getAdminArea() != null)
                		locationStr += myList.get(0).getAdminArea();
                    
            		DoWikiSearch wikiSearch = new DoWikiSearch(); 
            		performSearch(wikiSearch, locationStr);
                }               
        	}
        });
    }
	
    /** sets up the MapView and map marker */
	public void instantiateMap(String fact) {
    	
		mapView = (MapView) findViewById(R.id.map_view);           
    	mapView.setBuiltInZoomControls(true);
    	
    	List<Overlay> mapOverlays = mapView.getOverlays();
        Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
        myItemizedOverlay itemizedoverlay = new myItemizedOverlay(drawable, this);
        
        GeoPoint point = new GeoPoint(latE, lngE);

        OverlayItem overlayitem = new OverlayItem(point, locationStr, fact); 
        itemizedoverlay.addOverlay(overlayitem);
        mapOverlays.add(itemizedoverlay);
        
        mapView.getController().setZoom(10);
        mapView.getController().setCenter(point);
    }
	
	/** perform Asynchronous HTTP Request */
    public class DoWikiSearch extends AsyncTask<String, Void, List<WikiFacts>> {
    	
    	@Override
    	public List<WikiFacts> doInBackground(String... params) {
    		String query = params[0];
    		return wikiFactSearch.find(query);
    	}
    	
    	@Override
    	public void onPostExecute(final List<WikiFacts> result) {
    		runOnUiThread(new Runnable() {
    	    	public void run() {
    	    		if (progressDialog!=null) {
    	    			progressDialog.dismiss();
    	    			progressDialog = null;
    	    		}
    	    		if (result!=null) {
    					instantiateMap(WikiFacts.title + " - " + WikiFacts.description);
    				}	
    	    	}
    	    });
    	}
    }
    
    /** start WikiSearch */
	public void performSearch(DoWikiSearch task, String query) {
	        progressDialog = ProgressDialog.show(LocationAppActivity.this,
	                "Please wait...", "Retrieving data...", true, true);
	   
            task.execute(query);
            progressDialog.setOnCancelListener(new CancelTaskOnCancelListener(task)); 
	}

	/** Cancel WikiSearch if user clicks Cancel in Dialog **/
	private class CancelTaskOnCancelListener implements OnCancelListener {
		private AsyncTask<?, ?, ?> task;
		public CancelTaskOnCancelListener(AsyncTask<?, ?, ?> task) {
			this.task = task;
		}
		public void onCancel(DialogInterface dialog) {
			if (task!=null) {
	    		task.cancel(true);
	    	}
		}
	}
	
	/** Required for MapActivity */
	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
	
	/** Register for the updates when Activity is in foreground */
    @Override
	protected void onResume() {
		super.onResume();
	}
	
	/** Stop the updates when Activity is paused to save CPU */
	@Override
	protected void onPause() {
		super.onPause();
	}
	
	public static void setCoordinates(Double lat, Double lng) {
		latE = (int) (lat*1000000);
        lngE = (int) (lng*1000000);
	}
}